﻿using System;
using System.Reflection;

///Набор управляющих серелизацией атрибутов
namespace Grishko.SerilizeTools
{
    

    /// <summary>
    ///  Свойства помеченные данным атрибутом не учавствуют в серилизации 
    /// </summary>    
    [AttributeUsage(AttributeTargets.Property ,Inherited =true)]
    public class EntityNonSerialized: Attribute 
    {
        public EntityNonSerialized() { }

    }

    /// <summary>
    ///  Свойства помеченные данным атрибутом вызывают исключение при сохранениии 
    ///  в случае если поле null
    /// </summary>
    [AttributeUsage(AttributeTargets.Property, Inherited = true)]
    public class NotNullAttribute : Attribute
    {
        public NotNullAttribute() { }

    }


    /// <summary>
    ///  Указывает что данное свойство является интерфейсом или базовым классом 
    /// </summary>
    [AttributeUsage(AttributeTargets.Property, Inherited = true)]
    public class IsInterfaceEntity : Attribute
    {
        public IsInterfaceEntity() { }

    }

    /// <summary>
    /// Поисковая информация 
    /// </summary>
    [AttributeUsage(AttributeTargets.Property, Inherited = true)]
    public class SrchItemInfo : Attribute
    {
        public const string EmptyString = "EmptyString";        
        /// <summary>
        /// Text, Data, Number, Tree, TreeRB        
        ///  OnlyValueSrch Поиск по назначению - без указания типа
        /// </summary>
        public enum PropertyControlType { Text, Date, Number, Tree,Bool,OnlyValueSrch } ;        
        
        public SrchItemInfo() { }        
        
        public string  TxtPropertyName{get;set;}

        public PropertyControlType PropControlType { get; set; }
        
        private bool _ValueIsSqlFunction = false;
        
        /// <summary>
        /// Указывает что значением свойства является вызов SqlFunction
        /// </summary>
        public bool ValueIsSqlFunction { get { return _SqlFUnctionText.Length >0; } }

        private string _SqlFUnctionText = string.Empty;
        /// <summary>
        /// Указывает что значением свойства является вызов SqlFunction
        /// </summary>
        public String  SqlFunctionText { get { return _SqlFUnctionText; } set { _SqlFUnctionText = value; } }

        
        /// <summary>
        /// Параметр указывать только для спсиков. Значение указывает тип элементов списка.
        /// </summary>
        public Type ListType { get; set; }

        ///// <summary>
        ///// Параметр Помечает свойство как значение древовидного справочника        
        ///// </summary>        
        //private bool _IsTreeDictionaryValue=false ;
        //public bool IsTreeDictionaryValue { get { return _IsTreeDictionaryValue; } set { _IsTreeDictionaryValue = value;} }

        private string _TreeDictionaryTypeID=string .Empty ;
        /// <summary>
        /// категория справочника соотв. свойству справочника 
        /// </summary>
        public string TreeDictionaryTypeID { get { return _TreeDictionaryTypeID; } set { _TreeDictionaryTypeID = value; } }


        public string GetText_SqlFunctionCall(object objectValue)
        {
            string result = SqlFunctionText;
            object propertyValue = null;
            int firstBracket=-1;
            int lastBracket=-1;
            firstBracket=SqlFunctionText .IndexOf("("); 
            lastBracket=SqlFunctionText .IndexOf(")");
            // нет параметров
            if (-1 == firstBracket)
                return result;

            //есть параметры - подставляем реальные значения
            string s=SqlFunctionText .Substring (firstBracket+1 ,(lastBracket -firstBracket)-1 );
            string [] arr= s.Split (",".ToCharArray ());
            foreach (string i in arr)
            {                
                propertyValue = GetPropertyValue(objectValue, i.Replace  ("@",String .Empty));
                result = result.Replace(i, "'"+propertyValue.ToString()+"'");
            }
            
            
            return result ;

        }

        private object GetPropertyValue(object objectValue, string propertyName)
        {
            Type t = objectValue.GetType();
            PropertyInfo[] pi_lst = t.GetProperties();
            foreach (PropertyInfo p in pi_lst)
            {
                if (string.CompareOrdinal(p.Name, propertyName) == 0)
                {
                    return p.GetValue(objectValue, null);
                }
            }
            return null;
        }
        

    }

    [AttributeUsage(AttributeTargets.Class, Inherited = true)]
    public class TagNameInfo : Attribute
    {
        public TagNameInfo() { }
        public string TagName { get; set; }
    }

    /// <summary>
    /// Указывает ,что данный объект  НЕ пишется в табличку SrchStorageLinks
    /// Помечать - классы не явлющиеся бизнес объектами. 
    /// </summary>
    [AttributeUsage(AttributeTargets.Class, Inherited = true)]
    public class IsNotSrchStorageLinksObject  : Attribute
    {
        public IsNotSrchStorageLinksObject() { }
        public string TagName { get; set; }
    }

    /// <summary>
    /// атрибут - поле связка. 
    /// </summary>
    [AttributeUsage(AttributeTargets.Property, Inherited = true)]
    public class LinkFieldAttribute : SrchItemInfo
    {
        public LinkFieldAttribute(string linkField, string txtPropertyName) { LinkField = linkField; TxtPropertyName = txtPropertyName; }
        public string LinkField{ get; set; }
        public string PropertyField { get; set; }        

    }
}
